# -*- coding: utf-8 -*-

import re
import json
import os
import copy
from collections import OrderedDict
from config.rule import rule
from config import config

pre_path = "_MobaGoArt/Assets/"

gen_check_dir = ["_MobaGoArt/Assets/ArtAssets/character/Hero/Materials",
                 "_MobaGoArt/Assets/ArtAssets/character/Weapon/materials"]

workspace = config.read_config("ENV", "workspace_path")

_DESC = "_desc"
_OTHER = "_other"
_MATCH = "_match"
_RULE = "_rule"
_SEG = "_seg"
_REGEX = "_re"

_META = ".meta"


# 日志归类统计
def classify(log_lines, authors):
    classification = []
    no_matched = []

    for line in log_lines:
        line = line.strip()
        if line == "":
            continue
        author = authors.get(line, "||")
        ret = {"segment": "",
               "author": author,
               "full_path": "",
               "meta": False}
        meta = False
        abs_path = line
        if line.endswith(".meta"):
            meta = True
            line = line.split(".meta")[0]
        line = line.split(pre_path)[1]
        seg = line.split('/')

        if not seg[-1].find("."):
            commit_info = author.split("|")
            no_matched.append({"file": abs_path, "author": commit_info[0], "date": commit_info[1], "msg": commit_info[2]})
            continue

        # 根据规则，匹配出对应信息
        if walk_dict(rule, seg, ret, meta, abs_path, "", []):
            ret["full_path"] = abs_path
            ret["meta"] = meta
            classification.append(ret)
        elif len(filter(lambda x: x+"/gen_material" in abs_path, gen_check_dir)) == 0:
            commit_info = author.split("|")
            no_matched.append({"file": abs_path, "author": commit_info[0], "date": commit_info[1], "msg": commit_info[2]})

    return classification, no_matched


# 遍历字典，根据文件路径，提取相应信息
def walk_dict(rule_dict, seg, result, meta, path, dir_name, dir_matches):
    if _RULE in rule_dict:
        info = []
        try:
            rules = rule_dict[_RULE].split("|")
            if _REGEX in rule_dict:
                regexs = copy.deepcopy(rule_dict[_REGEX])
            for _rule in rules:
                if "$name_cur" == _rule:
                    # 本级名称
                    info.append(dir_name)

                elif "$name_rest" == _rule:
                    # 剩余路径
                    info.append("/".join(seg))

                elif "$name_next" == _rule:
                    # 下级名称
                    info.append(seg.pop(0))

                elif _rule.startswith("$dir_match_"):
                    # 父层级中匹配到的
                    n = int(_rule.split("_")[-1])
                    info.append(dir_matches[n])

                elif "$match" == _rule:
                    # 本级名称正则匹配

                    match_re = regexs.pop(0)
                    _match = re.match(match_re, dir_name.lower())

                    # 未匹配到
                    if not _match:
                        return False

                    num = match_re.count('(')

                    # 数据段数量不一致
                    if num != len(_match.groups()):
                        return False

                    for _mh in _match.groups():
                        info.append(_mh)

            msg_tmp = rule_dict[_SEG]
            msg = msg_tmp % tuple(info)

            result["segment"] = msg
            return True
        except Exception as e:
            return False

    if len(seg) == 0:
        return False

    current_key = seg.pop(0)
    current_dict = {}
    matched = False

    if current_key.lower() in rule_dict:
        matched = True
        current_dict = rule_dict[current_key.lower()]

    if not matched and _MATCH in rule_dict:
        matches = rule_dict[_MATCH]
        for match in matches:
            try:
                match_ret = re.match(match.keys()[0], current_key.lower())
                if match_ret:
                    matched = True
                    if len(match_ret.groups()) > 0:
                        dir_matches.append(match_ret.group(1))
                    current_dict = match.values()[0]
                    break
            except Exception as e:
                # print match
                pass

    if not matched and _OTHER in rule_dict:
        matched = True
        current_dict = rule_dict[_OTHER]

    if not matched:
        return False

    return walk_dict(current_dict, seg, result, meta, path, current_key, dir_matches)


def check_auto_gen(log_lines, authors):
    report_data = [
        {"title": u"英雄", "expoanded": True, "folder": True, "children": [
            {"title": u"材质", "folder": True, "children": []}
        ]},
        {"title": u"武器", "expoanded": True, "folder": True, "children": [
            {"title": u"材质", "folder": True, "children": []}
        ]}
    ]

    gen_dir = "gen_material/"
    startswith = ["_MobaGoArt/Assets/ArtAssets/character/Hero/Materials/",
                  "_MobaGoArt/Assets/ArtAssets/character/Weapon/materials/"]
    gen_type = ["_died.", "_frozen.", "_hide.", "_hurt.", "_invincible.", "_stone."]
    for line in log_lines:
        # _line = line.replace("\\", "/")
        ap_msg = ""
        author = authors.get(line, "||")
        abs_path = line

        if line.endswith(".meta"):
            ap_msg = u"_设置修改"
            line = line.split(".meta")[0]

        if line.startswith(startswith[0]) and not line.startswith(startswith[0] + gen_dir):
            parent_dir = startswith[0]
            category = 0
        elif line.startswith(startswith[1]) and not line.startswith(startswith[1] + gen_dir):
            parent_dir = startswith[1]
            category = 1
        else:
            continue

        gen_dir_path = parent_dir + gen_dir
        source_file = line.split(parent_dir)[1]
        commit_info = author.split("|")
        report_line = {"title": source_file + ap_msg, "pass": True, "full_path": abs_path, "auth": commit_info[0],
                       "commit_date": commit_info[1], "msg": commit_info[2], "children": []}
        for _type in gen_type:
            _gen_file = ".".join(source_file.split(".")[:-1]) + _type + source_file.split(".")[-1]
            _gen_file_path = gen_dir_path + _gen_file
            gen = True
            if _gen_file_path not in log_lines:
                gen = False
                report_line["pass"] = False
            report_line["children"].append(
                {"title": _gen_file, "gen": gen})
        report_data[category]["children"][0]["children"].append(report_line)
    return report_data


def modify_dict(seg, sub_dict, meta, author, full_path):
    if len(seg) == 0:
        return
    _s = seg.pop(0)
    if _s == u"武器":
        if seg[0] == u"武器_" or seg[0] == u"武器":
            seg[0] = u"武器_a"
        elif seg[0] == u"武器_1":
            seg[0] = u"武器_b"
        elif seg[0] == u"武器_2":
            seg[0] = u"武器_c"
        elif seg[0] == u"武器_3":
            seg[0] = u"武器_d"
        elif seg[0] == u"武器_5":
            seg[0] = u"武器_f"

    if _s not in sub_dict:
        if len(seg) == 1:
            try:
                sub_dict[_s] = [{"name": seg.pop(0) + meta, "author": author, "full_path": full_path}]
            except:
                print _s, seg[0]
            return
        else:
            sub_dict[_s] = {}
    else:
        if len(seg) == 1:
            try:
                sub_dict[_s].append({"name": seg.pop(0) + meta, "author": author, "full_path": full_path})
            except:
                print _s, seg[0]
            return
    _sub = sub_dict[_s]
    return modify_dict(seg, _sub, meta, author, full_path)


def to_web(title, info, index, ret):
    ret["title"] = title
    if index < 3:
        ret["expoanded"] = True
    if index < 4:
        ret["folder"] = True
    if len(info) > 0:
        if index > 1:
            ret["value"] = 1
        ret["children"] = []

    if type(info) == list:
        for _i in info:
            commit_info = _i["author"].split("|")
            ret["children"].append(
                {"title": _i["name"], "auth": commit_info[0], "commit_date": commit_info[1], "msg": commit_info[2],
                 "full_path": _i["full_path"]})
        return

    if type(info) == OrderedDict or type(info) == dict:
        for k, v in info.items():
            child = {}
            ret["children"].append(child)
            to_web(k, v, index+1, child)


def add_desc(report, desc_dict):
    if type(report) == list:
        for child in report:
            key = child["title"].replace(".", "?")
            if key in desc_dict:
                sub_desc_dict = desc_dict[key]
                if "_desc" in sub_desc_dict and sub_desc_dict["_desc"].strip() != "":
                    child["title"] += "(" + sub_desc_dict["_desc"] + ")"
                if "children" in child:
                    children = child["children"]
                    add_desc(children, sub_desc_dict)


if __name__ == '__main__':
    # report_data = ({
    #     u"英雄": {
    #         u"战斗内英雄": {},
    #     }
    # })
    sss = ["_MobaGoArt/Assets/ArtAssets/character/Weapon/materials/121weapon_b_sub.mat"]
    print classify(sss, {})
    # abs_path = "_MobaGoArt/Assets/ArtAssets/character/Weapon/materials/gen_material/117weapon_M_5_invincible.mat"
    # print filter(lambda x: x + "/gen_material" in abs_path, gen_check_dir)

    # _seg = u'英雄|战斗内英雄|601|特效|其它|601_0_1.prefab'.split("|")
    # modify_dict(_seg, report_data, "", "||", "")
    # print report_data
    # for root, info in report_data.items():
    #     child = {}
    #     to_web(root, info, 1, child)
    #
    #     print child





